package queue

import "container/list"

type Queue[T any] struct {
	size int
	l    *list.List
}

func New[T any]() *Queue[T] {
	return &Queue[T]{
		l: list.New(),
	}
}

func NewWithSize[T any](size int) *Queue[T] {
	if size <= 0 {
		panic("size can not be lower than 1")
	}
	return &Queue[T]{
		size: size,
		l:    list.New(),
	}
}

func (q *Queue[T]) Pop() (ret T) {
	if q.Len() == 0 {
		panic("empty queue!")
	}
	ret = q.l.Front().Value.(T)
	q.l.Remove(q.l.Front())
	return
}

func (q *Queue[T]) Push(v T) {
	if q.size != 0 && q.Len() >= q.size {
		return
	}
	q.l.PushBack(v)
}

func (q *Queue[T]) IsEmpty() bool {
	return q.l.Len() == 0
}

func (q *Queue[T]) Len() int {
	return q.l.Len()
}
